package com.anttribe.dbdocument.config;

import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author zhaoyong
 * @date 2021/10/6 0006
 */
@Slf4j
@Getter
@Setter
public class DBDataProcessorConfiguration {

    /**
     * 默认配置
     */
    private static final DBDataProcessorConfiguration DEFAULT_DB_DATAPROCESSOR_CONFIGURATION = DBDataProcessorConfiguration.builder().build();

    /**
     * 表名正则
     */
    private String tableNamePattern;

    /**
     * 默认构造器
     */
    private DBDataProcessorConfiguration() {
    }

    /**
     * 获取builder对象
     *
     * @return
     */
    public static DBDataProcessorConfigurationBuilder builder() {
        return new DBDataProcessorConfigurationBuilder();
    }

    /**
     * @author zhaoyong
     * @date 2021/10/6 0006
     */
    public static class DBDataProcessorConfigurationBuilder {

        /**
         * 默认表名正则
         */
        private static final String TABLE_NAME_PATTERN_REG = "(^_([a-zA-Z0-9]_?)+$)|(^[a-zA-Z](_?[a-zA-Z0-9])*_?$)";

        /**
         * 校验表名正则
         */
        private static final Pattern VERIFY_TABLE_NAME_PATTERN = Pattern.compile(TABLE_NAME_PATTERN_REG, Pattern.CASE_INSENSITIVE);

        /**
         * 校验表前缀正则
         */
        private static final String VERIFY_TABLE_PREFIX_PATTERN_REG = "(^_([a-zA-Z0-9]_?)+)|(^[a-zA-Z](_?[a-zA-Z0-9])*_?)";

        /**
         * 校验表前缀正则
         */
        private static final Pattern VERIFY_TABLE_PREFIX_PATTERN = Pattern.compile(VERIFY_TABLE_PREFIX_PATTERN_REG, Pattern.CASE_INSENSITIVE);

        /**
         * 校验表后缀正则
         */
        private static final String VERIFY_TABLE_SUFFIX_PATTERN_REG = "(_([a-zA-Z0-9]_?)+$)|([a-zA-Z](_?[a-zA-Z0-9])*_?$)";

        /**
         * 校验表后缀正则
         */
        private static final Pattern VERIFY_TABLE_SUFFIX_PATTERN = Pattern.compile(VERIFY_TABLE_SUFFIX_PATTERN_REG, Pattern.CASE_INSENSITIVE);

        /**
         * 排除的表名
         */
        private List<String> excludeTables;

        /**
         * 排除的表名的前缀
         */
        private List<String> excludeTablePrefixs;

        /**
         * 排除的表名的后缀
         */
        private List<String> excludeTableSuffixs;

        /**
         * 排除的数据库表名
         *
         * @param excludeTableNames
         * @return DBDataProcessorConfigurationBuilder
         */
        public DBDataProcessorConfigurationBuilder excludeTableNames(String... excludeTableNames) {
            if (!ArrayUtils.isEmpty(excludeTableNames)) {
                if (null == this.excludeTables) {
                    this.excludeTables = new ArrayList<String>();
                }

                // 对参数进行校验和处理， 符合表名规则
                for (String excludeTableName : excludeTableNames) {
                    Matcher m = VERIFY_TABLE_NAME_PATTERN.matcher(excludeTableName);
                    if (null != m && m.matches()) {
                        this.excludeTables.add(excludeTableName);
                    }
                }
            }
            return this;
        }

        /**
         * 排除的数据库表前缀
         *
         * @param excludeTablePrefixs
         * @return DBDataProcessorConfigurationBuilder
         */
        public DBDataProcessorConfigurationBuilder excludeTablePrefixs(String... excludeTablePrefixs) {
            if (!ArrayUtils.isEmpty(excludeTablePrefixs)) {
                if (null == this.excludeTablePrefixs) {
                    this.excludeTablePrefixs = new ArrayList<String>();
                }

                // 对参数进行校验和处理， 符合表名规则
                for (String excludeTablePrefix : excludeTablePrefixs) {
                    Matcher m = VERIFY_TABLE_PREFIX_PATTERN.matcher(excludeTablePrefix);
                    if (null != m && m.matches()) {
                        this.excludeTablePrefixs.add(excludeTablePrefix);
                    }
                }
            }
            return this;
        }

        /**
         * 排除的表后缀列表
         *
         * @param excludeTableSuffixs
         * @return DBDataProcessorConfigurationBuilder
         */
        public DBDataProcessorConfigurationBuilder excludeTableSuffixs(String... excludeTableSuffixs) {
            if (!ArrayUtils.isEmpty(excludeTableSuffixs)) {
                if (null == this.excludeTableSuffixs) {
                    this.excludeTableSuffixs = new ArrayList<String>();
                }

                // 对参数进行校验和处理， 符合表名规则
                for (String excludeTableSuffix : excludeTableSuffixs) {
                    Matcher m = VERIFY_TABLE_SUFFIX_PATTERN.matcher(excludeTableSuffix);
                    if (null != m && m.matches()) {
                        this.excludeTableSuffixs.add(excludeTableSuffix);
                    }
                }
            }
            return this;
        }

        /**
         * 构造DBDataProcessorConfiguration对象
         *
         * @return DBDataProcessorConfiguration
         */
        public DBDataProcessorConfiguration build() {
            DBDataProcessorConfiguration configuration = new DBDataProcessorConfiguration();
            String tableNamePattern = buildTableNamePattern();
            if (StringUtils.isEmpty(tableNamePattern)) {
                tableNamePattern = TABLE_NAME_PATTERN_REG;
            }
            configuration.setTableNamePattern(tableNamePattern);

            return configuration;
        }

        /**
         * 构造表名正则
         *
         * @return String
         */
        private String buildTableNamePattern() {
            StringBuilder tableNamePatternBuilder = new StringBuilder("");
            // 过滤表前缀
            List<String> excludeTablePrefixs = this.excludeTablePrefixs;
            if (!CollectionUtils.isEmpty(excludeTablePrefixs)) {
                tableNamePatternBuilder.append("^");
                int index = 0;
                for (String excludeTablePrefix : excludeTablePrefixs) {
                    if (index++ > 0) {
                        tableNamePatternBuilder.append("|");
                    }
                    tableNamePatternBuilder.append("(?!(").append(excludeTablePrefix).append("))");
                }
                // tableNamePatternBuilder.append(")");
            }

            // 过滤表
            List<String> excludeTables = this.excludeTables;
            if (!CollectionUtils.isEmpty(excludeTables)) {
            }

            // 过滤表后缀
            List<String> excludeTableSuffixs = this.excludeTableSuffixs;
            if (!CollectionUtils.isEmpty(excludeTableSuffixs)) {
                tableNamePatternBuilder.append("(");
                int index = 0;
                for (String excludeTableSuffix : excludeTableSuffixs) {
                    if (index > 0) {
                        tableNamePatternBuilder.append("|");
                    }
                    tableNamePatternBuilder.append("(?!").append(excludeTableSuffix).append(")");
                }
                tableNamePatternBuilder.append(")$");
            }

            return tableNamePatternBuilder.toString();
        }

    }
}
